#include "head.h" // <> 优先系统目录  "" 优先找当前，当前找不到找系统
int exitpipe[2];
void sighandler(int signum){
    printf("signum = %d\n", signum);
    write(exitpipe[1],"1",1);
}
int main(int argc, char *argv[])
{
    // ./server 192.168.118.128 1234 3
    ARGS_CHECK(argc,4);
    int workerNum = atoi(argv[3]);
    // 先准备保存每个子进程的信息
    workerdata_t * workerdataArr = (workerdata_t *)calloc(workerNum,sizeof(workerdata_t));
    // 创建workernum个子进程
    makeWorker(workerdataArr,workerNum);
    pipe(exitpipe);// 创建一个用于退出的管道
    signal(SIGUSR1,sighandler);
    // 调用tcpInit函数 socket bind listen
    int sockfd;
    tcpInit(argv[1],argv[2],&sockfd);
    // 创建epoll文件对象
    int epfd = epoll_create(1);
    // sockfd要加入监听
    epollAdd(epfd,sockfd);
    // 把每个子进程的管道加入监听
    for(int i = 0; i < workerNum; ++i){
        epollAdd(epfd,workerdataArr[i].pipefd);
    }
    epollAdd(epfd,exitpipe[0]);//监听退出管道的读端
    // 准备就绪集合
    int listenSize = 2 + workerNum; 
    struct epoll_event * readyset = (struct epoll_event *)calloc(listenSize,sizeof(struct epoll_event));
    while(1){
        int readyNum = epoll_wait(epfd,readyset,listenSize,-1);
        for(int i = 0; i < readyNum; ++i){
            if(readyset[i].data.fd == sockfd){
                //有客户端连接
                printf("Client connected!\n");
                int netfd = accept(sockfd,NULL,NULL);
                for(int j = 0; j < workerNum; ++j){//遍历所有子进程
                    if(workerdataArr[j].status == FREE){//找到第一个空闲的子进程
                        sendfd(workerdataArr[j].pipefd,netfd,0); // exitflag为0 说明不关闭
                        workerdataArr[j].status = BUSY;
                        break;
                    }
                }//更好的做法 是将所有空闲的子进程维持成一个队列
                close(netfd);//主进程断开netfd
            }
            else if(readyset[i].data.fd == exitpipe[0]){
                // 产生了10号信号
                for(int j = 0; j < workerNum; ++j){
                    //kill(workerdataArr[j].pid,SIGKILL);
                    //printf("kill 1 worker!\n");
                    printf("sendfd exitflag to child!\n");
                    sendfd(workerdataArr[j].pipefd,0,1); //exitflag为1，说明要关闭 
                }
                for(int j = 0; j < workerNum; ++j){
                    wait(NULL);
                }
                printf("parent is going to die!\n");
                exit(0);
            }
            else{
                // 子进程完成了任务
                printf("Worker finished!\n");
                // 顺序查找
                for(int j = 0; j < workerNum; ++j){
                    if(workerdataArr[j].pipefd == readyset[i].data.fd){
                        pid_t pid;
                        read(readyset[i].data.fd,&pid,sizeof(pid));
                        printf("No %d worker finished his job! pid = %d\n",j, pid);
                        workerdataArr[j].status = FREE;
                        break;
                    }
                }
            }
        }
    }
    return 0;
}

